package string;

import org.junit.Test;

/**
 * @Description 468. 验证IP地址
 * @Author Firenut
 * @Date 2023-04-29 22:13
 */
public class T468_validIPAddress {
    @Test
    public void test() {
        System.out.println(validIPAddress(".192.168.1.1."));
        System.out.println(validIPAddress(".192.168.1.1"));
        System.out.println(validIPAddress("192.168.1.1."));
        System.out.println(validIPAddress("192.168.1.1"));
//        validIPAddress("192.168.1.1");
        System.out.println(validIPAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
    }

    // .192.168.1.1. false
    // .192.168.1.1 false
    // 192.168.1.1. true
    // "1.0.1."
    // 本题其实就是一个过滤问题,考的是细节,需要把不符合条件的ip筛掉
    public String validIPAddress(String queryIP) {
        if (checkIPV4(queryIP)) {
            return "IPv4";
        }
        if (checkIPV6(queryIP)) {
            return "IPv6";
        }
        return "Neither";
    }

    boolean checkIPV4(String s) {
        int cnt = 0;  // 记录数字型的个数
        for (int i = 0; i < s.length() && cnt < 4;) {
            int j = i;
            int num = 0;
            // j < s.length() , 防止 j 越界
            while (j < s.length() && s.charAt(j) >= '0' && s.charAt(j) <= '9') {
                num = num * 10 + (s.charAt(j) - '0');
                j++;
            }
            // 没有找到数字项 or 存在前导0
            if (i == j || (j - i > 1 && s.charAt(i) == '0') || (j - i) > 3) {
                return false;
            }
            // 数字超过255
            if (num > 255) return false;

            i = j + 1;
            // 到达字符串末尾,则退出
            if (j == s.length()) break;

            // 分隔数字的字符不是 .
            if (s.charAt(j) != '.') return false;
            cnt++;
        }
        // case : "1.0.1."
        return cnt == 3 && s.charAt(s.length() - 1) != '.';
    }

    boolean checkIPV6(String s) {
        int cnt = 0;
        for (int i = 0; i < s.length() && cnt < 8;) {
            int j = i;
            while (j < s.length() && ((s.charAt(j) >= '0' && s.charAt(j) <= '9')
                    || (s.charAt(j)) >= 'a' && (s.charAt(j) <= 'f')
                    || (s.charAt(j) >= 'A' && s.charAt(j) <= 'F'))) {
                j++;
            }
            if (i == j || (j - i > 4)) {
                return false;
            }
            if (j < s.length() && s.charAt(j) != ':') {
                return false;
            }
            i = j + 1;
            if (j == s.length()) break;
            cnt++;
        }
        return cnt == 7 && s.charAt(s.length() - 1) != ':';
    }
}
